﻿using EventDemo.Evnets;
using System;
using System.Reflection;
using System.Threading;

namespace EventDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var 鱼竿 = new FishingRod();
            var jet = new FishingMan("Jet");// 垂钓者
            jet.FishingRod = 鱼竿; //分配了一个鱼竿

            鱼竿.FishingEvent += new FishingEventHandler().HandleEvent;//观察者

            while (jet.FishCount < 5)
            {
                jet.Fishing();
                Console.WriteLine("-------------------");
                //睡眠5s
                Thread.Sleep(5000);
            }
        }
    }

    public enum FishType
    {
        鲫鱼,
        鲤鱼,
        黑鱼,
        青鱼,
        草鱼,
        鲈鱼
    }
    /// <summary>
    /// 鱼竿
    /// </summary>
    public class FishingRod: IEventHandler<FishingEventData>
    {
        public FishingRod()
        {
            Assembly assembly = Assembly.GetExecutingAssembly();

            foreach (var type in assembly.GetTypes())
            {
                if (typeof(IEventHandler).IsAssignableFrom(type))//判断当前类型是否实现了IEventHandler接口
                {
                    Type handlerInterface = type.GetInterface("IEventHandler`1");//获取该类实现的泛型接口
                    Type eventDataType = handlerInterface.GetGenericArguments()[0]; // 获取泛型接口指定的参数类型

                    //如果参数类型是FishingEventData，则说明事件源匹配
                    if (eventDataType.Equals(typeof(FishingEventData)))
                    {
                        //创建实例
                        var handler = Activator.CreateInstance(type) as IEventHandler<FishingEventData>;
                        //注册事件
                        FishingEvent += handler.HandleEvent;
                    }
                }
            }
        }



        public delegate void FishingHandler(FishType type); //声明委托
        public event FishingHandler FishingEvent; //声明事件

        public void ThrowHook(FishingMan man)
        {
            Console.WriteLine("开始下钩！");

            //用随机数模拟鱼咬钩，若随机数为偶数，则为鱼咬钩
            if (new Random().Next() % 2 == 0)
            {
                var a = new Random(10).Next();
                var type = (FishType)new Random().Next(0, 5);
                Console.WriteLine("铃铛：叮叮叮，鱼儿咬钩了");
                if (FishingEvent != null)
                {
                    var eventData = new FishingEventData() { FishType = type, FishingMan = man };
                    //FishingEvent(eventData);//不再需要通过事件委托触发
                    EventBus.Default.Trigger<FishingEventData>(eventData);//直接通过事件总线触发即可
                }
            }
        }

        public void HandleEvent(FishingEventData eventData)
        {
            throw new NotImplementedException();
        }
    }


    public class FishingMan : IEventHandler<IEventData>
    {
        public FishingMan(string name)
        {
            Name = name;
        }

        public string Name { get; set; }
        public int FishCount { get; set; }

        /// <summary >
        /// 垂钓者自然要有鱼竿啊
        /// </summary >
        public FishingRod FishingRod { get; set; }

        public void Fishing()
        {
            this.FishingRod.ThrowHook(this);
        }

        public void Update(FishType type)
        {
            FishCount++;
            Console.WriteLine("{0}：钓到一条[{2}]，已经钓到{1}条鱼了！", Name, FishCount, type);
        }
      
        public void HandleEvent(IEventData eventData)
        {
            if (eventData is FishingEventData)
            {
                //do something
            }

            //if (eventData is XxxEventData)
            //{
            //    //do something else
            //}
        }
    }

    public class FishingEventData : EventData
    {
       
        public FishType FishType { get; set; }
        public FishingMan FishingMan { get; set; }
    }

    public class FishingEventHandler : IEventHandler<FishingEventData>
    {
        public void HandleEvent(FishingEventData eventData)
        {
            eventData.FishingMan.FishCount++;

            Console.WriteLine("{0}：钓到一条[{2}]，已经钓到{1}条鱼了！",
                eventData.FishingMan.Name, eventData.FishingMan.FishCount, eventData.FishType);

        }
    }


}
